package swings.panels;

import com.alibaba.fastjson.JSONObject;
import entity.CommonParam;
import entity.CommonRecord;
import entity.HttpResult;
import swings.buttons.CommonButton;
import swings.buttons.TabButton;
import swings.labels.BgLabel;
import swings.labels.LineLabel;
import swings.others.CommonJTextField;
import utils.*;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

/**
 * @version V1.0
 * @Title:
 * @Package
 * @Description:
 * @author: runoob
 * @date:
 */
public class WorkPanel extends CommonPanel{

    public static int x = 300;
    public static int y = 5;
    public static int width = 880;
    public static int height = 750;
    public static BgLabel bg = new BgLabel(x,y,width,height);
    private CommonJTextField urlField = new CommonJTextField(50);
//    public JLabel method = new JLabel();
    private CommonButton method = new CommonButton(ImageUtils.getImg,5,3,80,35);
    public ParamsPanel paramsPanel = new ParamsPanel();
    public HeadersPanel headersPanel = new HeadersPanel();
    public SecretsPanel secretsPanel = new SecretsPanel();
    public TemplatePanel templatePanel = new TemplatePanel();
    public Map<String, String> dataMap = new HashMap<>();
    public BodyPanel repDataPanel = new BodyPanel("");
    public BodyPanel repBodyPanel = new BodyPanel("");
    public HeadersPanel repHeadersPanel = new HeadersPanel(dataMap);
    public BodyPanel repInfoPanel = new BodyPanel("");
    public BodyPanel bodyPanel = new BodyPanel();
    public TabButton paramsBtn = new TabButton(5,48, "Params", this, paramsPanel);
    public TabButton headersBtn = new TabButton(100,48, "Headers", this, headersPanel);
    public TabButton secretsBtn = new TabButton(195,48, "Secrets", this, secretsPanel);
    public TabButton templateBtn = new TabButton(290,48, "Template", this, templatePanel);
    public TabButton bodyBtn = new TabButton(385,48, "Body", this, bodyPanel);
    public TabButton repDataBtn = new TabButton(5,height/2 + 12, "Data", this, repDataPanel);
    public TabButton repBodyBtn = new TabButton(100,height/2 + 12, "Body", this, repBodyPanel);
    public TabButton repHeadersBtn = new TabButton(195,height/2 + 12, "Headers", this, repHeadersPanel);
    public TabButton repInfoBtn = new TabButton(290,height/2 + 12, "Info", this, repInfoPanel);
    public CommonRecord record = new CommonRecord();
    private JLabel status = new JLabel();
    private JLabel time = new JLabel();

    public WorkPanel() throws IOException {
        initPanel();
        initBtns();
        initPanels();
    }

    public void initPanel(){
        Font font = CommonUtils.getFont();
        urlField.setFont(font);
        urlField.setForeground(Color.WHITE);
        urlField.setBounds(90,3,width-180,35);
        urlField.setOpaque(false);
        JLabel fieldBg = new JLabel();
        fieldBg.setIcon(ImageUtils.common);
        fieldBg.setBounds(90,3,width-180,35);
        status.setText("Status:");
        status.setFont(font);
        status.setForeground(Color.WHITE);
        status.setBounds(640,height/2 + 12,100,30);
        time.setText("Time:");
        time.setFont(font);
        time.setForeground(Color.WHITE);
        time.setBounds(745,height/2 + 12,130,30);
        this.setBounds(x,y,width,height);
        this.add(urlField);
        this.add(fieldBg);
        this.add(status);
        this.add(time);
        this.add(new LineLabel(0,39,width,5));
        this.add(new LineLabel(0,height/2 + 5,width,5));
    }

    public void initBtns(){
        CommonButton sendBtn = new CommonButton(ImageUtils.sendImg,width-85,3,80,35);
        sendBtn.addActionListener(new send());
        paramsBtn.setHold();
        repDataBtn.setHold();
        method.setIcon(new ImageIcon(ImageUtils.getImg));
        method.setMethodListener();
        method.removeButtonControl();
        this.add(sendBtn);
        this.add(paramsBtn);
        this.add(headersBtn);
        this.add(secretsBtn);
        this.add(templateBtn);
        this.add(bodyBtn);
        this.add(repDataBtn);
        this.add(repBodyBtn);
        this.add(repHeadersBtn);
        this.add(repInfoBtn);
        this.add(method);
    }

    public void initPanels(){
        paramsPanel.setVisible(true);
        headersPanel.setVisible(false);
        secretsPanel.setVisible(false);
        templatePanel.setVisible(false);
        bodyPanel.setVisible(false);
        repDataPanel.setVisible(true);
        repBodyPanel.setVisible(false);
        repHeadersPanel.setVisible(false);
        repInfoPanel.setVisible(false);
        this.add(paramsPanel);
        this.add(headersPanel);
        this.add(secretsPanel);
        this.add(templatePanel);
        this.add(bodyPanel);
        this.add(repDataPanel);
        this.add(repBodyPanel);
        this.add(repHeadersPanel);
        this.add(repInfoPanel);
    }

    public void setUrl(String data){
        urlField.setText(data);
        refresh();
    }

    public void setMethod(String data){
        if (data.equals("GET")){
            method.setIcon(ImageUtils.get);
            method.status = 0;
        }else {
            method.setIcon(ImageUtils.post);
            method.status = 1;
        }
        refresh();
    }

    private void refresh(){
        invalidate();
        validate();
        repaint();
    }

    private class send implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            try {
                getResult();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }

    private void getResult() throws Exception {
        String url = urlField.getText();
        String data;
        ArrayList<CommonParam> paramsList = paramsPanel.getData();
        ArrayList<CommonParam> headersList = headersPanel.getData();
        ArrayList<CommonParam> secretsList = secretsPanel.getData();
        ArrayList<CommonParam> templateList = templatePanel.getData();
        Connection connection = DataManageUtils.getConnection();
        Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
        updateParam(statement, paramsList, record.getId());
        updateHeader(statement, headersList, record.getId());
        updateTemplate(statement, templateList, record.getId());
        HttpResult result;
//        if (record.getMethod().equals("GET")){
        if (method.status == 0){
            if (bodyPanel.isVisible()){
                data = bodyPanel.textArea.getText();
            }else {
                data = CommonUtils.buildGetParam(paramsList);
            }
            result = HttpsUtil.doGet(url, data, headersList, this);
        }else {
            if (bodyPanel.isVisible()){
                data = bodyPanel.textArea.getText();
            }else {
                data = CommonUtils.getBody(CommonUtils.buildPostParam(paramsList), secretsList, templateList);
            }
            result = HttpsUtil.doPost(url, CommonUtils.formatJSON(data), headersList, this);
        }
        bodyPanel.setData(CommonUtils.formatJSON(data));
        AESUtils aesUtils = new AESUtils();
        String dataSecret = secretsList.get(0).getValue();
        String dataSecretIV = secretsList.get(1).getValue();
        String appSecret = secretsList.get(2).getValue();
        record.setUrl(url);
        record.setDataSecret(dataSecret);
        record.setDataSecretIV(dataSecretIV);
        record.setAppSecret(appSecret);
        record.setBody(bodyPanel.textArea.getText());
        record.setResult(CommonUtils.formatJSON(result.getData()));
        repBodyPanel.setData(CommonUtils.formatJSON(result.getData()));
        status.setText("Status: " + result.getStatus());
        time.setText("Time: " + result.getTime());
        if (result.getStatus().equals("200")){
            JSONObject object = JSONObject.parseObject(result.getData());
            setOtherPanel();
            if (method.status == 0){
                setBodyPanel("");
            }else {
                if (null!=object && object.containsKey(templateList.get(0).getKey())){
                    setDataPanel(CommonUtils.formatJSON(aesUtils.Decrypt(dataSecret,dataSecretIV,object.getString(templateList.get(0).getKey()))));
                }else {
                    setBodyPanel("");
                }
            }
        }else {
            setDataPanel(CommonUtils.formartHTML(result.getData()));
        }

        repHeadersPanel.setData(result.getHeaderMap());
        repHeadersPanel.removeAddParamLabel();
        repHeadersBtn.setRelease();
        repHeadersPanel.setVisible(false);
        updateRecord(statement);
        statement.close();
        connection.close();
    }

    public void setBodyPanel(String data){
        repDataBtn.setRelease();
        repBodyBtn.setHold();
        repDataPanel.setVisible(false);
        repBodyPanel.setVisible(true);
        repDataPanel.setData(data);
    }

    public void setDataPanel(String data){
        repBodyBtn.setRelease();
        repDataBtn.setHold();
        repBodyPanel.setVisible(false);
        repDataPanel.setVisible(true);
        repDataPanel.setData(data);
    }

    public void setOtherPanel(){
        repInfoBtn.setRelease();
        repHeadersBtn.setRelease();
        repInfoPanel.setVisible(false);
        repHeadersPanel.setVisible(false);
    }

    public void updateRecord(Statement statement) throws SQLException {
        Map<String,Object> valueMap = new HashMap<>();
        valueMap.put("id", record.getId());
        valueMap.put("title", record.getTitle());
        valueMap.put("url", record.getUrl());
        valueMap.put("method", record.getMethod());
        valueMap.put("dataSecret", record.getDataSecret());
        valueMap.put("dataSecretIV", record.getDataSecretIV());
        valueMap.put("appSecret", record.getAppSecret());
        valueMap.put("isEncrypt", record.getIsEncrypt());
        valueMap.put("body", record.getBody());
        valueMap.put("result", record.getResult());
        DataManageUtils.updateRecord(statement, valueMap);
//        DataManageUtils.insertRecord(statement, valueMap);
    }

    public void updateParam(Statement statement, ArrayList<CommonParam> paramsList, int id) throws SQLException {
        Map<String,Object> valueMap = new HashMap<>();
        valueMap.put("id", id);
        DataManageUtils.deleteParam(statement, valueMap);
        for (CommonParam param : paramsList){
            valueMap.put("paramkey", param.getKey());
            valueMap.put("paramvalue", param.getValue());
            valueMap.put("paramdescription", param.getDescription());
            DataManageUtils.insertParam(statement, valueMap);
        }
    }

    public void updateHeader(Statement statement, ArrayList<CommonParam> headersList, int id) throws SQLException {
        Map<String,Object> valueMap = new HashMap<>();
        valueMap.put("id", id);
        DataManageUtils.deleteHeader(statement, valueMap);
        for (CommonParam param : headersList){
            valueMap.put("headerkey", param.getKey());
            valueMap.put("headervalue", param.getValue());
            valueMap.put("headerdescription", param.getDescription());
            DataManageUtils.insertHeader(statement, valueMap);
        }
    }

    public void updateTemplate(Statement statement, ArrayList<CommonParam> paramsList, int id) throws SQLException {
        Map<String,Object> valueMap = new HashMap<>();
        valueMap.put("id", id);
        DataManageUtils.deleteTemplate(statement, valueMap);
        for (CommonParam param : paramsList){
            valueMap.put("templatekey", param.getKey());
            valueMap.put("templatevalue", param.getValue());
            valueMap.put("templatedescription", param.getDescription());
            DataManageUtils.insertTemplate(statement, valueMap);
        }
    }

}
